#include "Node.h"

CNode::CNode(int id)
{
	this->id = id;
	this->_gameObjects = NULL;
	this->childs = NULL;
}

CNode::CNode(int id, Rect* rect)
{
	this->id = id;
	this->_Bound = rect;
	this->_gameObjects = NULL;
	this->childs = NULL;
}

bool CNode::isLeaf()
{
	return _Bound->Width  <= SIZE_LEAF && _Bound->Height <= SIZE_LEAF;
}

void CNode::addGameObjects(AbstractEntity* obj)
{
	if(this->_gameObjects == NULL)
	{
		_gameObjects = new map<int, AbstractEntity*>();
	}
	_gameObjects->insert(make_pair(obj->getAbstractData()->getId(), obj));
}

void CNode::addChild(CNode* node)
{
	if(childs == NULL)
	{
		childs = new map<int, CNode*>();
	}
	childs->insert(make_pair(node->id, node));
	node->parent = this;
}


void CNode::getObject(map<int, AbstractEntity*>* currentObject, Rect* view)
{
	if(this->isLeaf())
	{

	}
	if(this->_Bound->IsIntersectAll(this->_Bound, view))
	{
		if(this->isLeaf())
		{
			this->_getObject(currentObject);
		}
		for(int i = this->id * NUM_NODE + 1; i <= this->id * NUM_NODE + 4; i++)
		{
			if(this->childs == NULL)
			{
				return;
			}
			childs->at(i)->getObject(currentObject, view);
		}
	}
}

void CNode::_getObject(map<int, AbstractEntity*>* currentObject)
{
	map<int, AbstractEntity*>::iterator it;
	if(_gameObjects == NULL)
	{
		return;
	}
	for(it = _gameObjects->begin(); it != _gameObjects->end(); it++)
	{
		currentObject->insert(make_pair(it->first, it->second));
	}
}

void CNode::deleteNode()
{
	if(this == NULL)
	{
		return;
	}
	map<int, CNode*>::iterator it;
	if(!this->isLeaf())
	{
		for(it = this->childs->begin(); it != this->childs->end(); it++)
		{
			it->second->deleteNode();
		}

	}
	// Test for load map
	if(this->parent != NULL && this->id != 1)
	{
		if(this->_Bound->Y > this->parent->_Bound->Y)
		{
			if(this->_Bound->X < this->parent->_Bound->X)
			{
				this->parent->childs->erase(0);
			}
			else
			{
				this->parent->childs->erase(1);
			}
		}
		else
		{
			if(this->_Bound->X < this->parent->_Bound->X)
			{
				this->parent->childs->erase(2);
			}
			else
			{
				this->parent->childs->erase(3);
			}
		}
	}

	delete this;
}

void CNode::deleteObjectsInNode()
{
	//Delete all object in node
	//if this is leaf -> delete all object in node
	//else delete object in this and childs
	if(this->isLeaf())
	{
		if(childs->size() > 0)
		{
			map<int, AbstractEntity*>::iterator it;
			for(it = this->_gameObjects->begin(); it != this->_gameObjects->end(); it++)
			{
				this->_gameObjects->erase(it);
			}
		}
		else
		{
			if(childs->size() > 0)
			{
				map<int, CNode*>::iterator it;
				for(it = this->childs->begin(); it != this->childs->end(); it++)
				{
					it->second->deleteObjectsInNode();
				}
			}
		}
	}
}


CNode::~CNode()
{
}


//how to delete node in tree
